import { _decorator, instantiate, Node, ProgressBar, tween, Tween, Vec3 } from 'cc';
import DataManager from '../../Global/DataManager';
import { EntityTypeEnum, IActor, InputTypeEnum, toFixed } from '../../Common';
import { EntityManager } from '../../Base/EntityManager';
import { ActorStateMachine } from './ActorStateMachine';
import { EntityStateEnum, EventEnum } from '../../Enum';
import { WeaponMgr } from '../Weapon/WeaponMgr';
import { rad2Angle } from '../../Utils';
import EventManager from '../../Global/EventManager';
const { ccclass, property } = _decorator;

@ccclass('ActorMgr')
export class ActorMgr extends EntityManager {
    bulletType:EntityTypeEnum;
    private wp :WeaponMgr = null;
    private id :number = 0;
    private hp :ProgressBar;
    private targetPos:Vec3;
    private tw:Tween<Node>;
    init(data:IActor) {
        this.fsm = this.addComponent(ActorStateMachine);
        this.fsm.init(data.type);
        this.hp = this.node.getComponentInChildren(ProgressBar);

        this.id = data.id;
        this.state = EntityStateEnum.Idle;
        this.bulletType = data.bulletType;

        const prefab = DataManager.Instance.prefabMap.get(EntityTypeEnum.Weapon1);
        const weapon1 = instantiate(prefab);
        weapon1.setParent(this.node);
        this.wp = weapon1.addComponent(WeaponMgr);
        this.wp.init(data);

        this.node.active = false;
        this.targetPos = undefined;
    }

    tick(dt: number) {
        if(this.id !== DataManager.Instance.myPlayerId) return;

        if (DataManager.Instance.jm.dir.length()) {
            const {x,y} = DataManager.Instance.jm.dir;
            EventManager.Instance.emit(EventEnum.ClientSync,{
                id: DataManager.Instance.myPlayerId,
                type: InputTypeEnum.ActorMove,
                direction:{
                    x:toFixed(x),
                    y:toFixed(y)
                },
                dt:toFixed(dt),
            })
        }
    }

    render(data:IActor) {
        this.renderPos(data);
        this.renderDirection(data);
        this.renderHp(data);
        
    }

    renderPos(data:IActor) {
        const {position} = data;
        const newPos  = new Vec3(position.x,position.y,0);
        if(!this.targetPos)
        {
            this.node.active = true;
            this.node.setPosition(newPos);
            this.targetPos = newPos.clone();
        } 
        else if(!this.targetPos.equals(newPos))
        {
            this.node.setPosition(this.targetPos);
            this.targetPos.set(newPos)
            this.state = EntityStateEnum.Run;
            this.tw?.stop();
            this.tw = tween(this.node).to(0.1,{position:this.targetPos})
            .call(() => {
                this.state = EntityStateEnum.Idle;
            })
            .start();
        }
    }

    renderDirection(data:IActor) {
        const {direction} = data;
        if(direction.x !== 0){
            this.node.setScale(direction.x>0 ? 1 : -1, 1)
            this.hp.node.setScale(direction.x>0? 1 : -1, 1)
        }

        const size = Math.sqrt(direction.x * direction.x + direction.y * direction.y);
        const rad = Math.asin(direction.y / size);
        const angle = rad2Angle(rad);

        this.wp.node.setRotationFromEuler(0,0,angle);
    }

    renderHp(data:IActor) {
        this.hp.progress = data.hp / this.hp.totalLength;
    }
}


